package com.xms.web.framework.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xms.configuration.model.PlatformSetting;
import com.xms.configuration.service.ISettingFactory;
import com.xms.security.identity.ICurrentUser;
import com.xms.utils.StringUtil;
import com.xms.utils.UUIDUtil;
import com.xms.web.framework.model.JsonResultObject;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ClassUtils;
import org.springframework.util.MimeTypeUtils;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.Date;

/**
 * <p>
 * ApiBaseController
 * </p>
 *
 * @author migo
 * @since 2021/9/2
 */
@RestController
public class ApiBaseController {
    protected ICurrentUser _currentUser;
    protected HttpServletRequest _request;
    protected HttpServletResponse _response;
    protected ISettingFactory _settingFactory;

    @Autowired
    public void ApiBaseController(ICurrentUser currentUser,
                                  ISettingFactory settingFactory,
                                  HttpServletRequest request,
                                  HttpServletResponse response) {
        _request = request;
        _response = response;
        _currentUser = currentUser;
        _settingFactory = settingFactory;
    }

    protected PlatformSetting getPlatformSettings() {
        try {
            return _settingFactory.getObject(PlatformSetting.class);
        } catch (Exception e) {
            return new PlatformSetting();
        }
    }

    protected JsonResultObject JError() {
        return JsonResultObject.failure("");
    }

    protected JsonResultObject JError(String content) {
        return JsonResultObject.failure(content);
    }

    protected JsonResultObject JOk(Object content) {
        return JsonResultObject.success(content);
    }

    protected JsonResultObject JOk() {
        return JsonResultObject.success("");
    }

    protected JsonResultObject JCreateFailure(String appendMsg) {
        return JsonResultObject.failure("新建失败：" + appendMsg);
    }

    protected JsonResultObject JCreateFailure() {
        return JsonResultObject.failure("新建失败");
    }

    protected JsonResultObject JCreateSuccess() {
        return JsonResultObject.success("新建成功", null);
    }

    protected JsonResultObject JCreateSuccess(Object extra) {
        return JsonResultObject.success("新建成功", extra);
    }

    protected JsonResultObject JUpdateFailure(String appendMsg) {
        return JsonResultObject.failure("更新失败:" + appendMsg);
    }

    protected JsonResultObject JUpdateFailure() {
        return JsonResultObject.failure("更新失败");
    }

    protected JsonResultObject JUpdateSuccess() {
        return JsonResultObject.success("更新成功");
    }

    protected JsonResultObject JUpdateSuccess(Object extra) {
        return JsonResultObject.success("更新成功", extra);
    }

    protected JsonResultObject JDeleteFailure(String appendMsg) {
        return JsonResultObject.failure("删除失败:" + appendMsg);
    }

    protected JsonResultObject JDeleteFailure() {
        return JsonResultObject.failure("删除失败");
    }

    protected JsonResultObject JDeleteSuccess() {
        return JsonResultObject.success("删除成功");
    }

    protected JsonResultObject JSaveFailure() {
        return JsonResultObject.failure("保存失败");
    }

    protected JsonResultObject JSaveFailure(String appendMsg) {
        return JsonResultObject.failure("保存失败:" + appendMsg);
    }

    protected JsonResultObject JSaveSuccess() {
        return JsonResultObject.success("保存成功");
    }

    protected JsonResultObject JNotSpecifiedRecord() {
        return JsonResultObject.failure("无指定记录");
    }

    protected JsonResultObject JNotFound() {
        return JsonResultObject.failure("没有找到记录");
    }

    protected JsonResultObject JNotFound(String appendMsg) {
        return JsonResultObject.failure("没有找到记录：" + appendMsg);
    }

    protected JsonResultObject JNotSpecifiedParams(String... args) {
        return JsonResultObject.failure("以下参数不能为空：" + String.join(", ", args));
    }

    protected JsonResultObject JUnauthorized(String appendMsg) {
        return JsonResultObject.failure("没有权限 " + appendMsg);
    }

    protected JsonResultObject JUnauthorized() {
        return JsonResultObject.failure("没有权限 ");
    }

    protected <T> LambdaQueryWrapper<T> getSortedQueryWrapper(String sortby, String sortdirection) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        //排序
        if (sortby != null) {
            if (sortdirection != null &&
                    (sortdirection.equalsIgnoreCase("desc") || sortdirection.equals("1"))) {
                queryWrapper.orderByDesc(sortby);
            } else {
                queryWrapper.orderByAsc(sortby);
            }
        } else {
            queryWrapper.orderByAsc("createdon");
        }
        return queryWrapper.lambda();
    }

    protected void writeFileStream(ByteArrayOutputStream stream, String mimeType, String name) throws IOException {
        if (StringUtil.isEmpty(mimeType)) {
            mimeType = MimeTypeUtils.APPLICATION_OCTET_STREAM_VALUE;
        }

        try (
                OutputStream outputStream = _response.getOutputStream();
        ) {
            _response.setContentType("application/x-download");
            _response.addHeader("Content-Type", mimeType + ";charset=UTF-8");
            _response.addHeader("Cache-Control", "no-cache, no-store, must-revalidate");
            _response.addHeader("Content-Disposition", "attachment; filename=" + new String(name.getBytes(StandardCharsets.UTF_8), "UTF-8"));
            _response.addHeader("Pragma", "no-cache");
            _response.addHeader("Expires", "0");
            _response.addHeader("Last-Modified", new Date().toString());
            _response.addHeader("ETag", String.valueOf(System.currentTimeMillis()));
            outputStream.write(stream.toByteArray());
            outputStream.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            _response.addHeader("Content-Type", "text/plain;charset=UTF-8");
            _response.getWriter().write("文件不存在");
            _response.flushBuffer();
        } catch (IOException e) {
            e.printStackTrace();
            _response.addHeader("Content-Type", "text/plain;charset=UTF-8");
            _response.getWriter().write(e.getMessage());
            _response.flushBuffer();
        }
    }

    protected void writeFileStream(File file, String mimeType, String name) throws IOException {
        if (file == null) {
            return;
        }
        if (StringUtil.isEmpty(mimeType)) {
            mimeType = MimeTypeUtils.APPLICATION_OCTET_STREAM_VALUE;
        }
        if (StringUtil.isEmpty(name)) {
            name = file.getPath().substring(file.getPath().lastIndexOf(java.io.File.separator));
        }
        else if(name.indexOf(".") < 0){
            name += file.getPath().substring(file.getPath().lastIndexOf("."));
        }

        try (
                InputStream inputStream = new FileInputStream(file);
                OutputStream outputStream = _response.getOutputStream();
        ) {
            _response.setContentType("application/x-download");
            _response.addHeader("Content-Type", mimeType + ";charset=UTF-8");
            _response.addHeader("Cache-Control", "no-cache, no-store, must-revalidate");
            //new String(name.getBytes(StandardCharsets.ISO_8859_1), "ISO-8859-1")
            _response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(name,"UTF-8"));
            _response.addHeader("Pragma", "no-cache");
            _response.addHeader("Expires", "0");
            _response.addHeader("Last-Modified", new Date().toString());
            _response.addHeader("ETag", String.valueOf(System.currentTimeMillis()));
            IOUtils.copy(inputStream, outputStream);
            outputStream.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            _response.addHeader("Content-Type", "text/plain;charset=UTF-8");
            _response.getWriter().write("文件不存在");
            _response.flushBuffer();
        } catch (IOException e) {
            e.printStackTrace();
            _response.addHeader("Content-Type", "text/plain;charset=UTF-8");
            _response.getWriter().write(e.getMessage());
            _response.flushBuffer();
        }
    }

    protected void writeFileStream(String filePath, String mimeType, String name) throws IOException {
        writeFileStream(new File(ClassUtils.getDefaultClassLoader().getResource("").getPath(), filePath), mimeType, name);
    }

    protected void writeJson(String json) {
        PrintWriter writer = null;
        _response.setCharacterEncoding("UTF-8");
        _response.setContentType("application/json; charset=utf-8");
        try {
            writer = _response.getWriter();
            writer.print(json);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (writer != null)
                writer.close();
        }
    }

    protected void writeText(String text) {
        PrintWriter writer = null;
        _response.setCharacterEncoding("UTF-8");
        _response.setContentType("text/plain; charset=utf-8");
        try {
            writer = _response.getWriter();
            writer.print(text);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (writer != null)
                writer.close();
        }
    }

    protected void redirectTo(String url) {
        try {
            _response.sendRedirect(url);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    protected void toErrorPage(String msg) {
        this.redirectTo("/error?msg=" + msg);
    }
}
